package org.yray.sip.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.yray.sip.wav.WavHeader;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

@Slf4j
public class G711Grabber {

    public static byte[] wavFull2G711(byte[] bs)
    {
        ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bs);
        FFmpegFrameGrabber grabber=new FFmpegFrameGrabber(byteArrayInputStream);
        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
        try {
            grabber.start();
            FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputStream, 1);
            // 码率恒定
            recorder.setAudioOption("crf","0");
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_PCM_ALAW);
            recorder.setAudioBitrate(16);
            recorder.setAudioChannels(1);
            recorder.setSampleRate(8000);
            recorder.setAudioQuality(0);
            recorder.setAudioOption("aq","10");
            recorder.setFormat("wav");
            recorder.start();
            Frame audioFrame = null;
            while ((audioFrame = grabber.grab()) != null) {
                recorder.setTimestamp(grabber.getTimestamp());
                recorder.record(audioFrame);
            }
            grabber.flush();
            grabber.stop();
            recorder.stop();
            recorder.release();
        } catch (Exception ex) {
            log.error("Exception:{}", ExceptionUtils.getStackTrace(ex));
        }
        return outputStream.toByteArray();
    }


    public static byte[] wavBody2G711(byte[] bs)
    {
        byte[] result=new byte[bs.length+44];
        WavHeader wavHeader=new WavHeader();
        wavHeader.setDataLen(bs.length);
        try{
            byte[] header= wavHeader.getHeaderByte();
            System.arraycopy(header,0,result,0,header.length);
        }
        catch (Exception e)
        {
            log.error(e.getMessage());
        }
        System.arraycopy(bs,0,result,44,bs.length);
        return wavFull2G711(result);
    }

    public static byte[] wavBody2G711Body(byte[] bs){
        byte[] full=wavBody2G711(bs);
        byte[] result=new byte[full.length-44];
        System.arraycopy(full,44,result,0,result.length);
        return result;
    }
}
